package com.base.lib.net;


import com.base.lib.net.listener.IHttpListener;
import com.base.lib.util.JSONUtils;
import com.base.lib.util.LogUtils;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.model.HttpParams;
import com.lzy.okgo.model.Response;
import com.lzy.okgo.request.base.Request;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author neo.duan
 * @date 2017/02/20
 * @desc 公共请求类
 */
public class HttpLoader {
    private final String TAG = HttpLoader.class.getSimpleName();

    public static HttpLoader getInstance() {
        return HttpLoaderHolder.INSTANCE;
    }

    private static class HttpLoaderHolder {
        private static final HttpLoader INSTANCE = new HttpLoader();
    }

    public void init() {

    }

    /**
     * 发送post请求
     */
    public void sendPostRequest(IBaseRequest request, IHttpListener listener) {
        HttpParams httpParams = new HttpParams();

        //添加header
        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, Object> entry : request.getHeaderParams().entrySet()) {
            headers.put(entry.getKey(), String.valueOf(entry.getValue()));
        }

        //遍历添加公共请求参数
        for (Map.Entry<String, Object> entry : request.getCommonParams().entrySet()) {
            httpParams.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        //遍历添加业务请求参数
        for (Map.Entry<String, Object> entry : request.getParams().entrySet()) {
            httpParams.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        String url = request.getBaseUrl() + request.getApi();
        OkGo.post(url)
                .tag(this)
                .params(httpParams)
                .headers(headers)
                .execute(new InnerCallBack(request, listener));
    }

    /**
     * 发送post json请求
     */
    public void sendPostJsonRequest(IBaseRequest request, IHttpListener listener) {
        String url = request.getBaseUrl() + request.getApi();
        String paramsJson = JSONUtils.getJsonString(request.getParams());

        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, Object> entry : request.getHeaderParams().entrySet()) {
            headers.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        OkGo.post(url)
                .tag(this)
                .headers(headers)
                .upJson(paramsJson)
                .execute(new InnerCallBack(request, listener));
    }

    /**
     * 发送post请求
     */
    public void sendGetRequest(IBaseRequest request, IHttpListener listener) {
        String url = request.getBaseUrl() + request.getApi();

        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, Object> entry : request.getHeaderParams().entrySet()) {
            headers.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        OkGo.get(url)
                .tag(this)
                .headers(headers)
                .execute(new InnerCallBack(request, listener));
    }

    /**
     * 发送put请求
     */
    public void sendPutRequest(IBaseRequest request, IHttpListener listener) {
        String url = request.getBaseUrl() + request.getApi();
        String paramsJson = JSONUtils.getJsonString(request.getParams());

        HttpHeaders headers = new HttpHeaders();
        for (Map.Entry<String, Object> entry : request.getHeaderParams().entrySet()) {
            headers.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        OkGo.put(url)
                .tag(this)
                .headers(headers)
                .upJson(paramsJson)
                .execute(new InnerCallBack(request, listener));
    }

    public void sendUploadFileRequest(IBaseRequest request, File file, IHttpListener listener) {
        String url = request.getBaseUrl() + request.getApi();
        String paramsJson = JSONUtils.getJsonString(request.getParams());

//        HttpHeaders headers = new HttpHeaders();
//        for (Map.Entry<String, Object> entry : request.getHeaderParams().entrySet()) {
//            headers.put(entry.getKey(), String.valueOf(entry.getValue()));
//        }
        OkGo.post(url)
                .tag(this)
                .headers(new HttpHeaders())
                .params("params", paramsJson)
                .params("file", file)
                .execute(new InnerCallBack(request, listener));
    }

    private class InnerCallBack<T> extends StringCallback {
        private IBaseRequest baseRequest;
        private IHttpListener listener;

        private InnerCallBack(IBaseRequest request, IHttpListener listener) {
            this.baseRequest = request;
            this.listener = listener;
        }

        /**
         * 请求网络开始前，UI线程
         */
        @Override
        public void onStart(Request<String, ? extends Request> request) {
            super.onStart(request);
            LogUtils.d(TAG, "onStart==" + request.getUrl() + "\n"
                    + baseRequest.getCommonParams() + "\n"
                    + baseRequest.getParams().toString());
            if (listener != null) {
                listener.onResponse(IHttpListener.RESPONSE_START, null, IHttpListener.STATUS_UNKNOWN);
            }
        }


        /**
         * 对返回数据进行操作的回调， UI线程
         */
        @Override
        public void onSuccess(Response<String> response) {
            LogUtils.d(TAG, "onSuccess==" + response.body());
            if (listener != null) {
                IServerResponse serverResponse = JSONUtils.parseObject(response.body(), baseRequest.getServerResponseClazz());
                //过关判断
                if (serverResponse == null) {
                    onError(response);
                    return;
                }
                //判断是否成功
                if (!serverResponse.isSuccess()) {
                    listener.onResponse(IHttpListener.RESPONSE_FAIL, serverResponse.getMessage(), IHttpListener.STATUS_UNKNOWN);
                    return;
                }

                //判断data数据是否需要解析
                Class responseClz = baseRequest.getResponseClazz();
                if (responseClz == null) {
                    listener.onResponse(IHttpListener.RESPONSE_SUCCESS, null, IHttpListener.STATUS_UNKNOWN);
                    return;
                }

                //服务器返回null
                Object responseBody = serverResponse.getBody();
                if (responseBody == null) {
                    listener.onResponse(IHttpListener.RESPONSE_SUCCESS, null, IHttpListener.STATUS_UNKNOWN);
                    return;
                }

                Object obj;
                //判断data数据是否为map, 是否解析成功
                if (responseBody instanceof Map) {
                    obj = JSONUtils.parseObject(serverResponse.getBody().toString(), responseClz);
                    if (obj == null) {
                        obj = Collections.EMPTY_LIST;
                    }
                    listener.onResponse(IHttpListener.RESPONSE_SUCCESS, obj, IHttpListener.STATUS_UNKNOWN);
                    return;
                }

                //判断data数据是否为list, 是否解析成功
                if (responseBody instanceof List) {
                    obj = JSONUtils.parseArray(serverResponse.getBody().toString(), responseClz);
                    if (obj == null) {
                        //解析出错了，服务器字段格式不正确
                        listener.onResponse(IHttpListener.RESPONSE_FAIL, "数据解析出错", IHttpListener.STATUS_UNKNOWN);
                    } else {
                        listener.onResponse(IHttpListener.RESPONSE_SUCCESS, obj, IHttpListener.STATUS_UNKNOWN);
                    }
                    return;
                }
            }
        }

        /**
         * 请求失败，响应错误，数据解析错误等，都会回调该方法， UI线程
         */
        @Override
        public void onError(Response<String> response) {
            super.onError(response);
            LogUtils.d(TAG, "onError==" + response.message());
            if (listener != null) {
                listener.onResponse(IHttpListener.RESPONSE_FAIL, null, IHttpListener.STATUS_UNKNOWN);
            }
        }

        /**
         * 请求网络结束后，UI线程
         */
        @Override
        public void onFinish() {
            super.onFinish();
            LogUtils.d(TAG, "onFinish==");
            if (listener != null) {
                listener.onResponse(IHttpListener.RESPONSE_DONE, null, IHttpListener.STATUS_UNKNOWN);
            }
        }
    }
}
